package com.utils.actionList
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	public class ActionList extends EventDispatcher
	{
		protected var _list:Array;
		
		
		public static const STATE_READY:int      = 0;
		public static const STATE_PROCESSING:int = 1;
		protected var _state:int = 0;
		
		protected var _currentItem:Object;
		
		public function ActionList(target:IEventDispatcher=null)
		{
			super(target);
			
			_list  = new Array();
			_state = STATE_READY;
		}
		
		public function start():void
		{
			if ( _state == STATE_PROCESSING ) return;
			
			_state = STATE_PROCESSING;
			nextItem();
		}
		
		public function clear():void
		{
			if ( _currentItem )
			{
				if ( _currentItem.owner )
				{
					_currentItem.owner.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_COMPLETE, onItemComplete);
					_currentItem.owner.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_ERROR,    onItemError);
				}
				
				_currentItem = null;
			}
			
			_list  = [];
			_state = STATE_READY; 
		}
		
		public function removeCurrentItem():void
		{
			if ( _state == STATE_PROCESSING ) return;
			
			if ( _currentItem )
			{
				if ( _currentItem.owner )
				{
					_currentItem.owner.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_COMPLETE, onItemComplete);
					_currentItem.owner.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_ERROR,    onItemError);
				}
				
				_currentItem = null;
			}
			
			_list.shift();
		}
		
		// ADD ///////////////////////////////////////////////////////////////////////////////////////
		public function add( owner:IEventDispatcher , method:Function , ... args):void
		{
			_list[_list.length] = {owner: owner,  method:method, params:args};
		}
		
		protected function onItemError(ev:ActionListEvent):void
		{
			ev.target.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_COMPLETE, onItemComplete);
			ev.target.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_ERROR,    onItemError);

			_state = STATE_READY;
			dispatchEvent( new ActionListEvent(ActionListEvent.EVT_ACTION_LIST_ERROR, ev.data ) );
		}

		protected function nextItem():void
		{
			if ( _list.length == 0 ) return;
			
			_currentItem = _list[0];
			var owner:IEventDispatcher = _currentItem.owner as IEventDispatcher;
			var method:Function        = _currentItem.method as Function;
			
			owner.addEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_COMPLETE, onItemComplete, false, 0, true);
			owner.addEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_ERROR, onItemError, false, 0, true);

			method.apply(owner, _currentItem.params);
		}
		
		protected function onItemComplete(ev:ActionListEvent):void
		{
			ev.target.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_COMPLETE, onItemComplete);
			ev.target.removeEventListener( ActionListEvent.EVT_ACTION_LIST_ITEM_ERROR,    onItemError);
			
			_list.shift();
			
			if ( _list.length == 0 ) 
			{
				_state = STATE_READY;
				dispatchEvent( new ActionListEvent(ActionListEvent.EVT_ACTION_LIST_COMPLETE) );
				return;
			}
			
			nextItem();
		}
	}
}